/****************************************
*
*	EoSC_AIController
*	
*	Handles all AI actions.
*
*	Thanks to Mougli @ http://www.moug-portfolio.info 
*	for his great implementation and of course thanks for sharing :)
*	Had to modify it a bit, to get it to work with the latest UDK (Feb.2012)
*
*	ToDo:
*	Needs to be extend for covers, position-switches and backstabs.
*
****************************************/

class EoSC_AIController extends GameAIController;

var Actor Player;
var() Vector TempDest;
var float PlayerDistance;

// Making sure the Controller has been called and that f. SUPER.POSTBEGINPLAY is THERE :D (took me 3 hrs to reconize that its needed)
simulated event PostBeginPlay()
{
	super.PostBeginPlay();
	`log("AI CONTROLLER HAS BEEN SPAWNED!");
}

// The pawn falls to the ground and will be switched to the default physics.
event Possess(Pawn inPawn, bool bVehicleTransition)
{
    super.Possess(inPawn, bVehicleTransition);
    Pawn.SetMovementPhysics();
}

// Always remain idle if theirs no pawn to follow.
auto state Idle
{
    event SeePlayer (Pawn Seen)
    {
        super.SeePlayer(Seen);
        Player = Seen;
		
		PlayerDistance = VSize( Pawn.Location - Player.location );
		
		// Make sure we're within fire-range.
		if (PlayerDistance < 200 )
		{
			GotoState('Shoot');
		}
		// If not Hunt him down!
		else
		{
			GotoState('Chase');
		}
	}
Begin:

}

/*	Go on a hunt if you see the player.
*	-ToDo:
*	Stop bots from chasing you all the time.
*/
state Chase
{
ignores SeePlayer;

function bool FindNavMeshPath()
	{
		// We need to clear cache
		NavigationHandle.PathConstraintList = none;
		NavigationHandle.PathGoalList = none;

		// Now lets create the constraints.
		class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Player );
		class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Player, 32 );

		// Can be uncommented, just here for debug purpose.
		Worldinfo.Game.Broadcast(self, "The goal is:"@Player);
		Worldinfo.Game.Broadcast(self, "Dest Location is:"@GetDestinationPosition());

		// Find Path
		return NavigationHandle.FindPath();
	}

Begin:
GetALocalPlayerController().Pawn;

PlayerDistance = VSize( Pawn.Location - Player.Location );
	if ( PlayerDistance < 200 )
	{
		GotoState('Shoot');
	}
	else if (NavigationHandle.ActorReachable( Player ) )
	{
		FlushPersistentDebugLines();
		MoveToward( Player, Player, 100 );
	}
	else if( FindNavMeshPath() )
	{
		NavigationHandle.SetFinalDestination(Player.location);
		FlushPersistentDebugLines();
		NavigationHandle.DrawPathCache(,TRUE);
	
	if( NavigationHandle.GetNextMoveLocation( TempDest, Pawn.GetCollisionRadius()) )
		{
			// Uncomment the next two lines when shipping, Debug stuff.
			DrawDebugLine(Pawn.Location,TempDest,255,0,0,true);
			DrawDebugSphere(TempDest,16,20,255,0,0,true);
			MoveTo( TempDest, Player );
		}
	}
	else
		{
			GotoState('Idle');
		}
	goto 'Begin';
}

// OMG we're close, shoot him!
state Shoot
{
ignores SeePlayer;
Begin:
	Player = GetALocalPlayerController().Pawn;
	Pawn.ZeroMovementVariables();
	Sleep(1);
	Pawn.StartFire(0);
	Pawn.StopFire(0);

	PlayerDistance = VSize( Pawn.Location - Player.Location );
	
	// If the player runs away make sure we're follow him rather than shooting all the time.
	if( PlayerDistance > 200 )
	{
		GotoState('Idle');
	}
	goto 'Begin';
}

defaultproperties
{
}